package com.example.dw.util;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class FormulaExecutorExample {

    public static void main(String[] args) {
        // 1. 创建公式执行器
        FormulaExecutor executor = new FormulaExecutor();

        // 2. 注册内置方法
        executor.registerStaticMethods(MathFormulaMethods.class);
        executor.registerStaticMethods(StringFormulaMethods.class);
        executor.registerStaticMethods(LogicFormulaMethods.class);
        executor.registerStaticMethods(BusinessFormulaMethods.class);

        // 3. 注册自定义实例方法
        CustomFormulaMethods customMethods = new CustomFormulaMethods();
        executor.registerObjectMethods(customMethods);

        // 4. 执行简单公式
        Object result1 = executor.execute("@add(5, 3)");
        System.out.println("5 + 3 = " + result1); // 输出: 8.0

        Object result2 = executor.execute("@concat('Hello, ', 'World!')");
        System.out.println("字符串连接: " + result2); // 输出: Hello, World!

        // 5. 执行嵌套公式
        Object result3 = executor.execute("@add(@multiply(2, 3), @subtract(10, 4))");
        System.out.println("复杂计算: " + result3); // 输出: 12.0

        // 6. 带上下文参数的公式
        Map<String, Object> context = new HashMap<>();
        context.put("price", 1000);
        context.put("discount", 20);

        Object result4 = executor.execute(
                "最终价格: @formatCurrency(@calculateDiscount(price, discount))", context);
        System.out.println(result4); // 输出: 最终价格: ¥800.00

        // 7. 逻辑公式
        Object result5 = executor.execute("@ifThenElse(@gt(85, 60), '及格', '不及格')");
        System.out.println("逻辑判断: " + result5); // 输出: 及格

        // 8. 混合公式
        Object result6 = executor.execute(
                "结果: @concat('得分:', @getGrade(85))");
        System.out.println(result6); // 输出: 结果: 得分:良好
    }

    /**
     * 自定义公式方法类
     */
    public static class CustomFormulaMethods {

        public String getCurrentTime() {
            return new java.util.Date().toString();
        }

        public String repeat(String str, Integer count) {
            return str+" "+count;
        }

        public Double average(List<Number> numbers) {
            return numbers.stream()
                    .mapToDouble(Number::doubleValue)
                    .average()
                    .orElse(0.0);
        }
    }
}
